package com.jfirer.jfireel.expression.node;

public interface MethodNode extends CalculateNode
{
    void setArgsNodes(CalculateNode[] argsNodes);

    enum ConvertType
    {
        INT, LONG, SHORT, FLOAT, DOUBLE, BYTE, BOOLEAN, CHARACTER, OTHER
    }

    class MethodNodeUtil
    {
        public static final void convertArgs(Object[] args, ConvertType[] convertTypes)
        {
            for (int i = 0; i < args.length; i++)
            {
                Object argeValue = args[i];
                switch (convertTypes[i])
                {
                    case INT:
                        if (argeValue instanceof Integer == false)
                        {
                            args[i] = ((Number) argeValue).intValue();
                        }
                        break;
                    case LONG:
                        if (argeValue instanceof Long == false)
                        {
                            args[i] = ((Number) argeValue).longValue();
                        }
                        break;
                    case SHORT:
                        if (argeValue instanceof Short == false)
                        {
                            args[i] = ((Number) argeValue).shortValue();
                        }
                        break;
                    case FLOAT:
                        if (argeValue instanceof Float == false)
                        {
                            args[i] = ((Number) argeValue).floatValue();
                        }
                        break;
                    case DOUBLE:
                        if (argeValue instanceof Double == false)
                        {
                            args[i] = ((Number) argeValue).doubleValue();
                        }
                        break;
                    case BYTE:
                        if (argeValue instanceof Byte == false)
                        {
                            args[i] = ((Number) argeValue).byteValue();
                        }
                        break;
                    case CHARACTER:
                    case BOOLEAN:
                    case OTHER:
                        // 以上三种不用转化
                        break;
                    default:
                        break;
                }
            }
        }

        public static final ConvertType[] buildConvertTypes(Class<?>[] parameterTypes)
        {
            ConvertType[] convertTypes = new ConvertType[parameterTypes.length];
            for (int i = 0; i < parameterTypes.length; i++)
            {
                if (parameterTypes[i] == int.class || parameterTypes[i] == Integer.class)
                {
                    convertTypes[i] = ConvertType.INT;
                }
                else if (parameterTypes[i] == short.class || parameterTypes[i] == short.class)
                {
                    convertTypes[i] = ConvertType.SHORT;
                }
                else if (parameterTypes[i] == long.class || parameterTypes[i] == Long.class)
                {
                    convertTypes[i] = ConvertType.LONG;
                }
                else if (parameterTypes[i] == float.class || parameterTypes[i] == Float.class)
                {
                    convertTypes[i] = ConvertType.FLOAT;
                }
                else if (parameterTypes[i] == double.class || parameterTypes[i] == Double.class)
                {
                    convertTypes[i] = ConvertType.DOUBLE;
                }
                else if (parameterTypes[i] == byte.class || parameterTypes[i] == Byte.class)
                {
                    convertTypes[i] = ConvertType.BYTE;
                }
                else if (parameterTypes[i] == boolean.class || parameterTypes[i] == Boolean.class)
                {
                    convertTypes[i] = ConvertType.BOOLEAN;
                }
                else
                {
                    convertTypes[i] = ConvertType.OTHER;
                }
            }
            return convertTypes;
        }

        public static final boolean isWrapType(Class<?> primitiveType, Class<?> arge)
        {
            if (primitiveType == int.class)
            {
                return arge == Integer.class || arge == Long.class;
            }
            else if (primitiveType == short.class)
            {
                return arge == Integer.class || arge == Long.class;
            }
            else if (primitiveType == long.class)
            {
                return arge == Integer.class || arge == Long.class;
            }
            else if (primitiveType == boolean.class)
            {
                return arge == Boolean.class;
            }
            else if (primitiveType == float.class)
            {
                return arge == Float.class || arge == Double.class;
            }
            else if (primitiveType == double.class)
            {
                return arge == Float.class || arge == Double.class;
            }
            else if (primitiveType == char.class)
            {
                return arge == Character.class;
            }
            else if (primitiveType == byte.class)
            {
                return arge == Integer.class || arge == Long.class;
            }
            else
            {
                return false;
            }
        }
    }
}
